/**
 * Copyright (C) 2010 Sergey Grigoriev <s.a.grigoriev@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.gmf.core

import com.google.inject.Inject
import org.apache.maven.project.MavenProject
import org.apache.maven.artifact.Artifact
import org.apache.maven.artifact.DefaultArtifact
import org.apache.maven.artifact.handler.ArtifactHandler
import org.apache.log4j.Logger
import org.apache.maven.plugin.MojoExecutionException
import org.apache.maven.model.Model
import org.apache.maven.model.io.xpp3.MavenXpp3Writer
import org.codehaus.plexus.util.WriterFactory

import org.apache.commons.io.IOUtils
import org.apache.maven.project.artifact.ProjectArtifactMetadata
import com.google.inject.name.Named
import net.gmf.dsl.FlexProject

/**
 * Creates and RSL from an swc
 */
class MakeRslCommand {

  @Inject
  private Logger log

  @Inject
  def FlexSdkFacade flexSdkFacade

  @Inject
  MavenProject project

  @Inject
  @Named('swfArtifactHandler')
  ArtifactHandler artifactHandler

  @Inject
  private FlexProject flexProject

  @Inject
  @Named('attachedArtifacts')
  private Set attachedArtifacts

  def run() {

    FlexProjectUtils flexProjectUtils = new FlexProjectUtils(project)

    def tmpFolder = File.createTempFile('gmf', 'unzip')
    tmpFolder.delete();
    tmpFolder.mkdir();

    new AntBuilder().unzip(src: flexProjectUtils.compilerOutput,
            dest: tmpFolder,
            overwrite: "false")
    log.debug 'finished unzipping'

    def librarySwf = [tmpFolder, 'library.swf'].join(File.separator)
    OSCommand cmd = flexSdkFacade.createCommand('optimizer', project)

    final def rsl = [project.build.directory, "${project.build.finalName}.swf"].join(File.separator)
    cmd << ['-input=': librarySwf, '-output=': rsl]
    cmd << flexProject.rootNode.makeRslNode.optimizer.ops

    cmd.run()

    updateDigest(rsl, flexProjectUtils.compilerOutput)
    def error = new AssertionError("Specify groupId and artifactId for generated RSL")
    if (!flexProject.rootNode.makeRslNode.artifact) {
      throw error;
    }
    def rslArtifactInfo
    try {
      rslArtifactInfo = FlexProjectUtils.parseArtifactString(flexProject.rootNode.makeRslNode.artifact)
    } catch (IllegalArgumentException e) {
      throw error;
    }
    Artifact artifact = new DefaultArtifact(
            rslArtifactInfo.groupId,
            rslArtifactInfo.artifactId,
            project.version,
            Artifact.SCOPE_COMPILE,
            'swf',
            null,
            artifactHandler
    )

    artifact.setFile(new File(rsl))
    artifact.addMetadata(new ProjectArtifactMetadata(artifact, generatePomFile(artifact)))
    project.addAttachedArtifact(artifact)
    attachedArtifacts.add(artifact)
  }

  def private updateDigest(rsl, swc) {
    if (!flexProject.rootNode.makeRslNode.digest) return
    OSCommand cmd = flexSdkFacade.createCommand('digest', project)
    cmd << ['-digest.rsl-file=': rsl, '-digest.swc-path=': swc]
    cmd.run()
  }

  private File generatePomFile(Artifact artifact) throws MojoExecutionException {
    Model model = generateModel(artifact);

    Writer writer
    try {
      File pom = File.createTempFile("rsl-install", ".pom");
      writer = WriterFactory.newXmlWriter(pom)
      new MavenXpp3Writer().write(writer, model)
      pom.deleteOnExit()
      return pom
    } finally {
      IOUtils.closeQuietly(writer)
    }
  }

  /**
   * Generates Model.
   *
   * @return The generated model
   */
  private Model generateModel(Artifact artifact) {
    Model model = new Model();

    model.setModelVersion("4.0.0");

    model.setGroupId(artifact.groupId);
    model.setArtifactId(artifact.artifactId);
    model.setVersion(artifact.version);
    model.setPackaging(artifact.type);

    model.setDescription("POM was automatically created when generating RSL");

    return model;
  }

}
